source('R-libraries-ICdD_p2.r')
df= read_csv("global_air_quality_data_10000.csv") %>% data.frame()
head(df)
##             City  Country       Date  PM2.5   PM10   NO2   SO2   CO     O3
## 1        Bangkok Thailand 2023-03-19  86.57  25.19 99.88 30.63 4.46  36.29
## 2       Istanbul   Turkey 2023-02-16  50.63  97.39 48.14  8.71 3.40 144.16
## 3 Rio de Janeiro   Brazil 2023-11-13 130.21  57.22 98.51  9.92 0.12 179.31
## 4         Mumbai    India 2023-03-16 119.70 130.52 10.96 33.03 7.74  38.65
## 5          Paris   France 2023-04-04  55.20  36.62 76.85 21.85 2.00  67.09
## 6    Los Angeles      USA 2023-01-05 121.28 196.39 86.17 28.74 2.64  46.86
##   Temperature Humidity Wind.Speed
## 1       17.67    59.35      13.76
## 2        3.46    67.51       6.36
## 3       25.29    29.30      12.87
## 4       23.15    99.97       7.71
## 5       16.02    90.28      14.16
## 6       18.53    43.01       3.96
df |> dim()
## [1] 10000    12
df |> 
  vis_dat() +
  labs(title = "Estructura y Clases de Variables del Conjunto de Calidad del Aire") +
  theme(
    plot.title = element_text(hjust = 0.5),
    axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=0),
    axis.text.y = element_text(size = 8)
  )

df |> skimr::skim() |> skimr::yank("character")

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
City 0 1 5 14 0 20 0
Country 0 1 2 12 0 19 0
df |> skimr::skim() |> skimr::yank("Date")

Variable type: Date

skim_variable n_missing complete_rate min max median n_unique
Date 0 1 2023-01-01 2023-12-28 2023-06-27 336
max(df$Date)-min(df$Date)
## Time difference of 361 days

Observación. Si existe datos pérdidos, en teoría debio pasar 361 días y solo se cuentan 336 registros únicos

Antes de completar las fechas, vamos a evitar duplicados de cada dia - Ciudad - País

df1 <- df %>%
  group_by(Country, City, Date) %>%
    summarise(
    across(where(is.numeric), ~mean(.x, na.rm = TRUE)),
  ) %>%
  ungroup()
## `summarise()` has grouped output by 'Country', 'City'. You can override using
## the `.groups` argument.
dim(df1)
## [1] 5203   12
head(df1)
## # A tibble: 6 × 12
##   Country   City   Date       PM2.5  PM10   NO2   SO2    CO    O3 Temperature
##   <chr>     <chr>  <date>     <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>       <dbl>
## 1 Australia Sydney 2023-01-02  74.7  70.6  33.8  20.2  3.36  84.6        7.15
## 2 Australia Sydney 2023-01-03  58.2 129.   62.0  36.6  4.65 106.        11.6 
## 3 Australia Sydney 2023-01-04 109.   89.8  43.5  17.8  3.35 139.        18.8 
## 4 Australia Sydney 2023-01-05  16.3  95.6  67.3  14.7  7.05  72.8        6.22
## 5 Australia Sydney 2023-01-06 144.   29    73.9  16.2  0.14 157         31.1 
## 6 Australia Sydney 2023-01-07 100.   99.7  55.3  18.1  6.77  88.1       11.8 
## # ℹ 2 more variables: Humidity <dbl>, Wind.Speed <dbl>
f_i <- min(df1$Date)
f_f <- max(df1$Date)

rango_completo_fechas <- seq.Date(from = f_i, to = f_f, by = "day")

dfc <- df1 %>%
  complete(
    nesting(City, Country), 
    Date = rango_completo_fechas
  )

dfc <- dfc %>% 
  arrange(Country, City, Date)

# Revisa el resultado:
glimpse(dfc)
## Rows: 7,240
## Columns: 12
## $ City        <chr> "Sydney", "Sydney", "Sydney", "Sydney", "Sydney", "Sydney"…
## $ Country     <chr> "Australia", "Australia", "Australia", "Australia", "Austr…
## $ Date        <date> 2023-01-01, 2023-01-02, 2023-01-03, 2023-01-04, 2023-01-0…
## $ PM2.5       <dbl> NA, 74.74333, 58.24500, 109.41500, 16.32000, 144.36000, 10…
## $ PM10        <dbl> NA, 70.63000, 128.91500, 89.81000, 95.63000, 29.00000, 99.…
## $ NO2         <dbl> NA, 33.82000, 61.95000, 43.47500, 67.29000, 73.86000, 55.3…
## $ SO2         <dbl> NA, 20.216667, 36.575000, 17.810000, 14.710000, 16.230000,…
## $ CO          <dbl> NA, 3.363333, 4.655000, 3.350000, 7.050000, 0.140000, 6.77…
## $ O3          <dbl> NA, 84.55667, 105.70500, 138.96500, 72.75000, 157.00000, 8…
## $ Temperature <dbl> NA, 7.153333, 11.600000, 18.765000, 6.220000, 31.130000, 1…
## $ Humidity    <dbl> NA, 55.40333, 78.97500, 44.20500, 19.99000, 14.92000, 45.7…
## $ Wind.Speed  <dbl> NA, 8.793333, 4.100000, 10.255000, 10.760000, 12.200000, 1…
dfc |> vis_dat()

dfc |> skimr::skim() |> skimr::yank("numeric")

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
PM2.5 2037 0.72 77.19 34.36 5.03 52.37 77.18 101.81 149.96 ▃▆▇▆▃
PM10 2037 0.72 104.18 44.89 10.07 71.88 104.40 135.95 199.91 ▃▆▇▆▃
NO2 2037 0.72 51.97 22.27 5.01 36.14 52.33 68.14 99.98 ▃▅▇▆▂
SO2 2037 0.72 25.30 11.53 1.01 17.31 25.34 33.33 49.95 ▃▅▇▅▃
CO 2037 0.72 5.05 2.31 0.10 3.42 5.06 6.67 10.00 ▃▆▇▅▃
O3 2037 0.72 105.69 45.15 10.05 72.98 105.82 138.15 199.90 ▃▆▇▆▃
Temperature 2037 0.72 14.95 11.68 -10.00 6.84 14.85 23.21 39.98 ▃▆▇▆▃
Humidity 2037 0.72 55.22 21.02 10.01 40.22 55.28 70.32 99.92 ▃▆▇▆▃
Wind.Speed 2037 0.72 10.22 4.64 0.51 6.92 10.24 13.46 19.99 ▃▆▇▆▃
dim(dfc)
## [1] 7240   12
missing_summary <- dfc %>%
  group_by(Country, City) %>%
  summarise(
    Dias_Totales_Rango = n(), 
    Dias_Faltantes = sum(is.na(PM2.5)), 
    Porcentaje_Faltante = (Dias_Faltantes / Dias_Totales_Rango) * 100
  ) %>%
  
  # 3. Ordenamos para ver los peores casos primero
  arrange(desc(Porcentaje_Faltante))
## `summarise()` has grouped output by 'Country'. You can override using the
## `.groups` argument.
print(missing_summary)
## # A tibble: 20 × 5
## # Groups:   Country [19]
##    Country      City       Dias_Totales_Rango Dias_Faltantes Porcentaje_Faltante
##    <chr>        <chr>                   <int>          <int>               <dbl>
##  1 Australia    Sydney                    362            114                31.5
##  2 Mexico       Mexico Ci…                362            113                31.2
##  3 USA          New York                  362            111                30.7
##  4 UAE          Dubai                     362            110                30.4
##  5 UK           London                    362            107                29.6
##  6 Brazil       Rio de Ja…                362            106                29.3
##  7 China        Beijing                   362            106                29.3
##  8 South Korea  Seoul                     362            106                29.3
##  9 Japan        Tokyo                     362            105                29.0
## 10 Egypt        Cairo                     362            104                28.7
## 11 Turkey       Istanbul                  362            103                28.5
## 12 Germany      Berlin                    362            101                27.9
## 13 USA          Los Angel…                362            100                27.6
## 14 Thailand     Bangkok                   362             98                27.1
## 15 France       Paris                     362             97                26.8
## 16 India        Mumbai                    362             95                26.2
## 17 Russia       Moscow                    362             93                25.7
## 18 South Africa Johannesb…                362             91                25.1
## 19 Spain        Madrid                    362             89                24.6
## 20 Canada       Toronto                   362             88                24.3
dfc |> plot_num()
## Warning: attributes are not identical across measure variables; they will be
## dropped

dfc |> freq()

##              City frequency percentage cumulative_perc
## 1         Bangkok       362          5               5
## 2         Beijing       362          5              10
## 3          Berlin       362          5              15
## 4           Cairo       362          5              20
## 5           Dubai       362          5              25
## 6        Istanbul       362          5              30
## 7    Johannesburg       362          5              35
## 8          London       362          5              40
## 9     Los Angeles       362          5              45
## 10         Madrid       362          5              50
## 11    Mexico City       362          5              55
## 12         Moscow       362          5              60
## 13         Mumbai       362          5              65
## 14       New York       362          5              70
## 15          Paris       362          5              75
## 16 Rio de Janeiro       362          5              80
## 17          Seoul       362          5              85
## 18         Sydney       362          5              90
## 19          Tokyo       362          5              95
## 20        Toronto       362          5             100

##         Country frequency percentage cumulative_perc
## 1           USA       724         10              10
## 2     Australia       362          5              15
## 3        Brazil       362          5              20
## 4        Canada       362          5              25
## 5         China       362          5              30
## 6         Egypt       362          5              35
## 7        France       362          5              40
## 8       Germany       362          5              45
## 9         India       362          5              50
## 10        Japan       362          5              55
## 11       Mexico       362          5              60
## 12       Russia       362          5              65
## 13 South Africa       362          5              70
## 14  South Korea       362          5              75
## 15        Spain       362          5              80
## 16     Thailand       362          5              85
## 17       Turkey       362          5              90
## 18          UAE       362          5              95
## 19           UK       362          5             100
## [1] "Variables processed: City, Country"
dfc %>% select(,City,Country) %>% unique()
## # A tibble: 20 × 2
##    City           Country     
##    <chr>          <chr>       
##  1 Sydney         Australia   
##  2 Rio de Janeiro Brazil      
##  3 Toronto        Canada      
##  4 Beijing        China       
##  5 Cairo          Egypt       
##  6 Paris          France      
##  7 Berlin         Germany     
##  8 Mumbai         India       
##  9 Tokyo          Japan       
## 10 Mexico City    Mexico      
## 11 Moscow         Russia      
## 12 Johannesburg   South Africa
## 13 Seoul          South Korea 
## 14 Madrid         Spain       
## 15 Bangkok        Thailand    
## 16 Istanbul       Turkey      
## 17 Dubai          UAE         
## 18 London         UK          
## 19 Los Angeles    USA         
## 20 New York       USA
df2 <- dfc %>%
  mutate(Continent = case_when
         (
           Country %in% c('Turkey','UAE','China','South Korea','Japan','India','Thailand') ~ "Asia",
           Country %in% c('Egypt','South Africa') ~ "Africa",
           Country %in% c('Canada','Mexico','USA') ~ "N-America",
           Country %in% c('Brazil') ~ "S-America",
           Country %in% c('Russia','Spain','Germany','UK','France') ~ "Europe",
           Country %in% c('Australia') ~ "Oceania"
         ))
df2 <- df2 %>%
  mutate(Hemisphere = case_when
         (
           Country %in% c('Turkey','UAE','China','South Korea','Japan','India','Thailand') ~ "North",
           Country %in% c('Egypt') ~ "North",
           Country %in% c('South Africa') ~ "South",
           Country %in% c('Canada','Mexico','USA') ~ "North",
           Country %in% c('Brazil') ~ "South",
           Country %in% c('Russia','Spain','Germany','UK','France') ~ "North",
           Country %in% c('Australia') ~ "South"
         ))
head(df2)
## # A tibble: 6 × 14
##   City   Country   Date       PM2.5  PM10   NO2   SO2    CO    O3 Temperature
##   <chr>  <chr>     <date>     <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>       <dbl>
## 1 Sydney Australia 2023-01-01  NA    NA    NA    NA   NA     NA         NA   
## 2 Sydney Australia 2023-01-02  74.7  70.6  33.8  20.2  3.36  84.6        7.15
## 3 Sydney Australia 2023-01-03  58.2 129.   62.0  36.6  4.65 106.        11.6 
## 4 Sydney Australia 2023-01-04 109.   89.8  43.5  17.8  3.35 139.        18.8 
## 5 Sydney Australia 2023-01-05  16.3  95.6  67.3  14.7  7.05  72.8        6.22
## 6 Sydney Australia 2023-01-06 144.   29    73.9  16.2  0.14 157         31.1 
## # ℹ 4 more variables: Humidity <dbl>, Wind.Speed <dbl>, Continent <chr>,
## #   Hemisphere <chr>

¿Ocurrencia por fecha específica?

df2 %>%
  gg_miss_span(
    var = Date,           
    span_every = 30,      
    facet = City        
  ) +
  labs(title = "Patrón de Días Faltantes (NA) a lo largo del Tiempo",
       x = "Bloque de 30 Días",
       y = "Conteo de Días Faltantes") +
  theme_minimal()

# Compara el % de NA para todas las variables, agrupado por Ciudad
df2 %>%
  gg_miss_fct(fct = Continent) +
  labs(title = "Datos Faltantes por Ciudad")+
  theme(
    axis.text.x = element_text(angle = 0, vjust = 0.5, hjust = 1)
  )

# Compara el % de NA para todas las variables, agrupado por Ciudad
df2 %>% filter(Continent == 'Africa') %>%
  gg_miss_fct(fct = City) +
  labs(title = "Datos Faltantes por ciudad en Africa")+
  theme(
    axis.text.x = element_text(angle = 0, vjust = 0.5, hjust = 1)
  )

# Compara el % de NA para todas las variables, agrupado por Ciudad
df2 %>% filter(Continent == 'Asia') %>%
  gg_miss_fct(fct = City) +
  labs(title = "Datos Faltantes por ciudad en Asia")+
  theme(
    axis.text.x = element_text(angle = 0, vjust = 0.5, hjust = 1)
  )

# Compara el % de NA para todas las variables, agrupado por Ciudad
df2 %>% filter(Continent == 'Europe') %>%
  gg_miss_fct(fct = City) +
  labs(title = "Datos Faltantes por ciudad en Europa")+
  theme(
    axis.text.x = element_text(angle = 0, vjust = 0.5, hjust = 1)
  )

# Compara el % de NA para todas las variables, agrupado por Ciudad
df2 %>% filter(Continent == 'Europe') %>%
  gg_miss_fct(fct = City) +
  labs(title = "Datos Faltantes por ciudad en Europa")+
  theme(
    axis.text.x = element_text(angle = 0, vjust = 0.5, hjust = 1)
  )

# Compara el % de NA para todas las variables, agrupado por Ciudad
df2 %>% filter(Continent == 'N-America') %>%
  gg_miss_fct(fct = City) +
  labs(title = "Datos Faltantes por ciudad en Norte Ámercia")+
  theme(
    axis.text.x = element_text(angle = 0, vjust = 0.5, hjust = 1)
  )

# Compara el % de NA para todas las variables, agrupado por Ciudad
df2 %>% filter(Continent == 'Oceania') %>%
  gg_miss_fct(fct = City) +
  labs(title = "Datos Faltantes por ciudad en Oceanía")+
  theme(
    axis.text.x = element_text(angle = 0, vjust = 0.5, hjust = 1)
  )

# Compara el % de NA para todas las variables, agrupado por Ciudad
df2 %>% filter(Continent == 'S-America') %>%
  gg_miss_fct(fct = City) +
  labs(title = "Datos Faltantes por ciudad en Sur Ámercia")+
  theme(
    axis.text.x = element_text(angle = 0, vjust = 0.5, hjust = 1)
  )

resumen_faltantes <- df2 %>%
  # 1. Agrupamos por las dos variables
  group_by(Country, City) %>%
  
  # 2. Calculamos las estadísticas
  summarise(
    #Total_Dias = n(),   
    Faltantes_PM25 = sum(is.na(PM2.5)), 
    #Porcentaje_PM25 = round(mean(is.na(PM2.5)) * 100, 2), 
    .groups = "drop"
  ) %>%
  
  # 3. Ordenamos para ver los peores casos arriba
  arrange(desc(Faltantes_PM25))

# Ver la tabla
print(resumen_faltantes)
## # A tibble: 20 × 3
##    Country      City           Faltantes_PM25
##    <chr>        <chr>                   <int>
##  1 Australia    Sydney                    114
##  2 Mexico       Mexico City               113
##  3 USA          New York                  111
##  4 UAE          Dubai                     110
##  5 UK           London                    107
##  6 Brazil       Rio de Janeiro            106
##  7 China        Beijing                   106
##  8 South Korea  Seoul                     106
##  9 Japan        Tokyo                     105
## 10 Egypt        Cairo                     104
## 11 Turkey       Istanbul                  103
## 12 Germany      Berlin                    101
## 13 USA          Los Angeles               100
## 14 Thailand     Bangkok                    98
## 15 France       Paris                      97
## 16 India        Mumbai                     95
## 17 Russia       Moscow                     93
## 18 South Africa Johannesburg               91
## 19 Spain        Madrid                     89
## 20 Canada       Toronto                    88
df_i <- df2 %>%

  group_by(Country, City) %>%
  arrange(Date) %>%
  mutate(across(
    where(is.numeric), 
    ~zoo::na.approx(., na.rm = FALSE)
  )) %>%
  
  fill(
    where(is.numeric), 
    .direction = "downup"
  ) %>%
  

  ungroup()

# Verificación final
sum(is.na(df_i$PM2.5))
## [1] 0
head(df_i)
## # A tibble: 6 × 14
##   City        Country Date       PM2.5  PM10   NO2   SO2    CO    O3 Temperature
##   <chr>       <chr>   <date>     <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>       <dbl>
## 1 Sydney      Austra… 2023-01-01  74.7  70.6  33.8  20.2  3.36  84.6        7.15
## 2 Rio de Jan… Brazil  2023-01-01  31.3  97.8  49.4  26.4  6.51 160.        15   
## 3 Toronto     Canada  2023-01-01 149.   98.0  73.0  43.5  9.38 178.        -5.05
## 4 Beijing     China   2023-01-01  70.9  60.7  53.4  38.2  5.61  33.8        7.39
## 5 Cairo       Egypt   2023-01-01  81.9  97.9  36.7  34.2  3.88 106.         2.16
## 6 Paris       France  2023-01-01  81.8  12.0  55.0  27.4  3.02  66.3        4.92
## # ℹ 4 more variables: Humidity <dbl>, Wind.Speed <dbl>, Continent <chr>,
## #   Hemisphere <chr>
df_i |> vis_dat()

df_i |> skimr::skim() |> skimr::yank("numeric")

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
PM2.5 0 1 77.27 32.11 5.03 54.57 77.06 99.41 149.96 ▂▆▇▅▂
PM10 0 1 103.84 42.02 10.07 74.83 103.82 133.17 199.91 ▂▆▇▅▂
NO2 0 1 52.03 20.76 5.01 38.00 52.25 66.66 99.98 ▂▅▇▆▂
SO2 0 1 25.37 10.73 1.01 18.15 25.43 32.74 49.95 ▂▅▇▅▂
CO 0 1 5.04 2.16 0.10 3.56 5.04 6.51 10.00 ▂▅▇▅▂
O3 0 1 105.88 42.10 10.05 76.37 106.28 135.41 199.90 ▂▅▇▆▂
Temperature 0 1 14.99 10.94 -10.00 7.58 14.89 22.62 39.98 ▂▅▇▅▂
Humidity 0 1 55.10 19.63 10.01 41.35 54.96 68.77 99.92 ▂▆▇▆▂
Wind.Speed 0 1 10.22 4.34 0.51 7.24 10.25 13.18 19.99 ▂▅▇▆▂
df_i |> plot_num()
## Warning: attributes are not identical across measure variables; they will be
## dropped

dfc |> freq()

##              City frequency percentage cumulative_perc
## 1         Bangkok       362          5               5
## 2         Beijing       362          5              10
## 3          Berlin       362          5              15
## 4           Cairo       362          5              20
## 5           Dubai       362          5              25
## 6        Istanbul       362          5              30
## 7    Johannesburg       362          5              35
## 8          London       362          5              40
## 9     Los Angeles       362          5              45
## 10         Madrid       362          5              50
## 11    Mexico City       362          5              55
## 12         Moscow       362          5              60
## 13         Mumbai       362          5              65
## 14       New York       362          5              70
## 15          Paris       362          5              75
## 16 Rio de Janeiro       362          5              80
## 17          Seoul       362          5              85
## 18         Sydney       362          5              90
## 19          Tokyo       362          5              95
## 20        Toronto       362          5             100

##         Country frequency percentage cumulative_perc
## 1           USA       724         10              10
## 2     Australia       362          5              15
## 3        Brazil       362          5              20
## 4        Canada       362          5              25
## 5         China       362          5              30
## 6         Egypt       362          5              35
## 7        France       362          5              40
## 8       Germany       362          5              45
## 9         India       362          5              50
## 10        Japan       362          5              55
## 11       Mexico       362          5              60
## 12       Russia       362          5              65
## 13 South Africa       362          5              70
## 14  South Korea       362          5              75
## 15        Spain       362          5              80
## 16     Thailand       362          5              85
## 17       Turkey       362          5              90
## 18          UAE       362          5              95
## 19           UK       362          5             100
## [1] "Variables processed: City, Country"

Cambio a data set Long

df_long <- df_i %>% 
    pivot_longer(!c(City, Country, Date,Continent,Hemisphere), names_to = "Metrica", values_to = "valor")
df_long |> head()
## # A tibble: 6 × 7
##   City   Country   Date       Continent Hemisphere Metrica valor
##   <chr>  <chr>     <date>     <chr>     <chr>      <chr>   <dbl>
## 1 Sydney Australia 2023-01-01 Oceania   South      PM2.5   74.7 
## 2 Sydney Australia 2023-01-01 Oceania   South      PM10    70.6 
## 3 Sydney Australia 2023-01-01 Oceania   South      NO2     33.8 
## 4 Sydney Australia 2023-01-01 Oceania   South      SO2     20.2 
## 5 Sydney Australia 2023-01-01 Oceania   South      CO       3.36
## 6 Sydney Australia 2023-01-01 Oceania   South      O3      84.6
df_long %>%
  ggplot(mapping = aes(x = Hemisphere, y = valor, fill = Hemisphere)) +
  geom_boxplot() +
  facet_wrap(~ Metrica, scales = "free", ncol = 3) + # <-- 1. Reducimos el número de columnas
  scale_fill_viridis_d(option = "plasma", end = .7) + # <-- 2. Corregido a scale_fill
  labs(
    title = "Comparación de Variables de Calidad del Aire por Hemisferio",
    x = "Hemisferio", # <-- 3. Añadimos etiquetas a los ejes
    y = "Valor"
  ) +
  theme_minimal() + # <-- 4. Usamos un tema base más limpio
  theme(
    # --- Ajustes para reducir el amontonamiento ---
    axis.text.x = element_text(angle = 90, hjust = 1, size = 7), # <-- 5. Rotamos y achicamos el texto del eje X
    strip.text = element_text(size = 8, face = "bold"), # <-- 6. Achicamos el texto de las facetas
    axis.title = element_text(size = 9), # <-- 7. Ajustamos el tamaño de los títulos de los ejes
    
    # --- Ajustes adicionales ---
    plot.title = element_text(hjust = 0.5, size = 16), # Centramos y ajustamos el título principal
    legend.position = "none" # Mantenemos la leyenda oculta
  )

df_long %>%
  ggplot(mapping = aes(x = valor, fill = Hemisphere)) + # <-- 1. 'valor' en el eje X
  
  # 2. Usamos geom_density en lugar de histograma
  geom_density(alpha = 0.7) + 
  
  facet_wrap(~ Metrica, scales = "free", ncol = 3) + 
  scale_fill_viridis_d(option = "plasma", end = .7) + 
  labs(
    title = "Densidad de Variables de Calidad del Aire por Hemisferio",
    x = "Valor de la Métrica", # <-- 3. Actualizamos etiquetas
    y = "Densidad"
  ) +
  theme_minimal() +
  theme(
    strip.text = element_text(size = 8, face = "bold"), 
    axis.title = element_text(size = 9), 
    plot.title = element_text(hjust = 0.5, size = 16),
    legend.position = "right"
  )

df_long %>%
  ggplot(mapping = aes(x = Continent, y = valor, fill = Continent)) +
  geom_boxplot() +
  facet_wrap(~ Metrica, scales = "free", ncol = 3) + # <-- 1. Reducimos el número de columnas
  scale_fill_viridis_d(option = "plasma", end = .7) + # <-- 2. Corregido a scale_fill
  labs(
    title = "Comparación de Variables de Calidad del Aire por Continente",
    x = "Continent", # <-- 3. Añadimos etiquetas a los ejes
    y = "Valor"
  ) +
  theme_minimal() + # <-- 4. Usamos un tema base más limpio
  theme(
    # --- Ajustes para reducir el amontonamiento ---
    axis.text.x = element_text(angle = 90, hjust = 1, size = 7), # <-- 5. Rotamos y achicamos el texto del eje X
    strip.text = element_text(size = 8, face = "bold"), # <-- 6. Achicamos el texto de las facetas
    axis.title = element_text(size = 9), # <-- 7. Ajustamos el tamaño de los títulos de los ejes
    
    # --- Ajustes adicionales ---
    plot.title = element_text(hjust = 0.5, size = 16), # Centramos y ajustamos el título principal
    legend.position = "none" # Mantenemos la leyenda oculta
  )

df_long %>%
  ggplot(mapping = aes(x = valor, fill = Continent)) + # <-- 1. 'valor' en el eje X
  
  # 2. Usamos geom_density en lugar de histograma
  geom_density(alpha = 0.7) + 
  
  facet_wrap(~ Metrica, scales = "free", ncol = 3) + 
  scale_fill_viridis_d(option = "plasma", end = .7) + 
  labs(
    title = "Densidad de Variables de Calidad del Aire por Continente",
    x = "Valor de la Métrica", # <-- 3. Actualizamos etiquetas
    y = "Densidad"
  ) +
  theme_minimal() +
  theme(
    strip.text = element_text(size = 8, face = "bold"), 
    axis.title = element_text(size = 9), 
    plot.title = element_text(hjust = 0.5, size = 16),
    legend.position = "right"
  )

df_long %>%
  ggplot(mapping = aes(x = Country, y = valor, fill = Country)) +
  geom_boxplot() +
  facet_wrap(~ Metrica, scales = "free", ncol = 3) + # <-- 1. Reducimos el número de columnas
  scale_fill_viridis_d(option = "plasma", end = .7) + # <-- 2. Corregido a scale_fill
  labs(
    title = "Comparación de Variables de Calidad del Aire por País",
    x = "Hemisferio", # <-- 3. Añadimos etiquetas a los ejes
    y = "Valor"
  ) +
  theme_minimal() + # <-- 4. Usamos un tema base más limpio
  theme(
    # --- Ajustes para reducir el amontonamiento ---
    axis.text.x = element_text(angle = 90, hjust = 1, size = 7), # <-- 5. Rotamos y achicamos el texto del eje X
    strip.text = element_text(size = 8, face = "bold"), # <-- 6. Achicamos el texto de las facetas
    axis.title = element_text(size = 9), # <-- 7. Ajustamos el tamaño de los títulos de los ejes
    
    # --- Ajustes adicionales ---
    plot.title = element_text(hjust = 0.5, size = 16), # Centramos y ajustamos el título principal
    legend.position = "none" # Mantenemos la leyenda oculta
  )

columnas_numericas <- c("PM2.5", "PM10", "NO2", "SO2", "CO", "O3", 
                        "Temperature", "Humidity", "Wind.Speed")

ggpairs(
  df_i,
  columns = columnas_numericas,
  progress = FALSE,
  mapping = aes(color = Continent), 
  
  title = "Matriz de Correlación y Dispersión por Continente",
  upper = list(
    continuous = wrap(ggally_cor, size = 2)
  )

) +
  theme_minimal()+
  theme(
  plot.title = element_text(size = 16, hjust = 0.5),
  strip.text = element_text(size = 5, face = "bold"),
  axis.text = element_text(size = 6),
  legend.position = "bottom",
  legend.title = element_text(size = 10),
  legend.text = element_text(size = 8),
  # Quita el fondo del panel (el área donde se dibujan los puntos)
    panel.background = element_blank(), 
    
    # Quita el fondo general de todo el gráfico
    plot.background = element_blank(), 
    
    # Quita las líneas de la cuadrícula (grid)
    panel.grid = element_blank(),
    
    # (Opcional) Quita el borde del panel, si es que aparece
    panel.border = element_blank()
  )

columnas_numericas <- c("PM2.5", "PM10", "NO2", "SO2", "CO", "O3", 
                        "Temperature", "Humidity", "Wind.Speed")

ggpairs(
  df_i,
  columns = columnas_numericas,
  progress = FALSE,
  mapping = aes(color = Hemisphere), 
  
  title = "Matriz de Correlación y Dispersión por Hemisferio",
  upper = list(
    continuous = wrap(ggally_cor, size = 2)
  )

) +
  theme_minimal()+
  theme(
  plot.title = element_text(size = 16, hjust = 0.5),
  strip.text = element_text(size = 5, face = "bold"),
  axis.text = element_text(size = 6),
  legend.position = "bottom",
  legend.title = element_text(size = 10),
  legend.text = element_text(size = 8),
  # Quita el fondo del panel (el área donde se dibujan los puntos)
    panel.background = element_blank(), 
    
    # Quita el fondo general de todo el gráfico
    plot.background = element_blank(), 
    
    # Quita las líneas de la cuadrícula (grid)
    panel.grid = element_blank(),
    
    # (Opcional) Quita el borde del panel, si es que aparece
    panel.border = element_blank()
  )

df_long %>%
  filter(Metrica == 'O3') %>%
  ggplot(mapping = aes(x = valor, fill = Continent)) +
  # 1. Usamos 'alpha' para transparencia en lugar de 'color'
  geom_density(alpha = 0.7, show.legend = TRUE) + 
  facet_wrap(~Metrica, scales = "free", ncol = 3) + # <-- 2. Reducimos el número de columnas
  scale_fill_viridis_d(option = "plasma", end = .7) +  # <-- 3. Corregido a scale_fill_*
  labs(
    title = "Distribución de Variables de O3", # <-- 4. Título único y claro
    x = "Valor del Feature",
    y = "Densidad",
    fill = "Continente" # Título para la leyenda
  ) +
  theme_minimal() +
  theme(
    # --- Ajustes de tamaño y posición ---
    plot.title = element_text(size = 16, hjust = 0.5),    # Título principal
    strip.text = element_text(size = 9, face = "bold"), # Títulos de las facetas (más pequeños)
    axis.title = element_text(size = 10),               # Títulos de los ejes
    axis.text = element_text(size = 8),                 # Texto en los ejes (números)
    
    legend.position = "bottom",                         # <-- 5. Movemos la leyenda abajo
    legend.title = element_text(size = 10),             # Título de la leyenda
    legend.text = element_text(size = 8)                # Texto de la leyenda (más pequeño)
  )

df_long %>%
  filter(Metrica == 'PM2.5') %>%
  ggplot(mapping = aes(x = valor, fill = Hemisphere)) +
  # 1. Usamos 'alpha' para transparencia en lugar de 'color'
  geom_density(alpha = 0.7, show.legend = TRUE) + 
  facet_wrap(~Metrica, scales = "free", ncol = 3) + # <-- 2. Reducimos el número de columnas
  scale_fill_viridis_d(option = "plasma", end = .7) +  # <-- 3. Corregido a scale_fill_*
  labs(
    title = "Distribución de Variables de la PM 2.5", # <-- 4. Título único y claro
    x = "Valor del Feature",
    y = "Densidad",
    fill = "Hemisferio" # Título para la leyenda
  ) +
  theme_minimal() +
  theme(
    # --- Ajustes de tamaño y posición ---
    plot.title = element_text(size = 16, hjust = 0.5),    # Título principal
    strip.text = element_text(size = 9, face = "bold"), # Títulos de las facetas (más pequeños)
    axis.title = element_text(size = 10),               # Títulos de los ejes
    axis.text = element_text(size = 8),                 # Texto en los ejes (números)
    
    legend.position = "bottom",                         # <-- 5. Movemos la leyenda abajo
    legend.title = element_text(size = 10),             # Título de la leyenda
    legend.text = element_text(size = 8)                # Texto de la leyenda (más pequeño)
  )

df_promedio_continente <- df_i %>%
  group_by(Continent, Date) %>%
  summarise(
    PM2.5_Promedio = mean(PM2.5, na.rm = TRUE),
    .groups = "drop"
  )

df_promedio_continente %>%
  ggplot(aes(x = Date, y = PM2.5_Promedio, color = Continent)) +
  
  geom_line(size = 0.8) +
  
  # CAMBIO CLAVE AQUÍ:
  # scales = "fixed" obliga a que todos los gráficos compartan el mismo eje Y.
  # (Es el comportamiento por defecto, así que también podrías borrar el argumento scales)
  facet_wrap(~ Continent, scales = "fixed", ncol = 2) +
  
  scale_color_viridis_d(option = "turbo") +
  theme_minimal() +
  labs(
    title = "Tendencia Promedio de PM2.5 por Continente (Escala Comparativa)",
    subtitle = "Todos los paneles usan el mismo rango en el eje Y para comparar magnitudes",
    y = "Promedio PM2.5 (µg/m³)",
    x = "Fecha"
  ) +
  theme(
    legend.position = "none", 
    strip.text = element_text(size = 11, face = "bold"),
    axis.text.x = element_text(angle = 45, hjust = 1),
    
    # Opcional: Agregar líneas de cuadrícula más claras para facilitar la lectura
    panel.grid.major.y = element_line(color = "gray90")
  )
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

library(dplyr)
library(ggplot2)


df_promedio_continente <- df_i %>% 
  group_by(Continent, Date) %>%
  summarise(
    PM2.5_Promedio = mean(PM2.5, na.rm = TRUE),
    Temp_Promedio = mean(Temperature, na.rm = TRUE), 
    .groups = "drop"
  )

max_pm <- max(df_promedio_continente$PM2.5_Promedio, na.rm = TRUE)
max_temp <- max(df_promedio_continente$Temp_Promedio, na.rm = TRUE)
scale_factor <- max_pm / max_temp 

df_promedio_continente %>%
  ggplot(aes(x = Date)) +
  geom_line(aes(y = PM2.5_Promedio, color = "PM2.5"), size = 0.8) +
  geom_line(aes(y = Temp_Promedio * scale_factor, color = "Temperatura"), 
            size = 0.8, linetype = "dashed") +
    facet_wrap(~ Continent, scales = "fixed", ncol = 2) +
  scale_y_continuous(
    name = "Promedio PM2.5 (µg/m³)",
    sec.axis = sec_axis(~ . / scale_factor, name = "Temperatura (°C)") 
  ) +
  
  scale_color_manual(values = c("PM2.5" = "black", "Temperatura" = "blue")) +
  
  theme_minimal() +
  labs(
    title = "Relación entre PM2.5 y Temperatura por Continente",
    subtitle = "PM2.5 (Línea sólida, Eje Izq) vs Temperatura (Línea punteada, Eje Der)",
    x = "Fecha",
    color = "Variable" 
  ) +
  theme(
    strip.text = element_text(size = 11, face = "bold"),
    axis.text.x = element_text(angle = 45, hjust = 1),
    legend.position = "bottom",

    axis.title.y.left = element_text(color = "black", face = "bold"),
    axis.title.y.right = element_text(color = "blue", face = "bold", vjust = 1.5) 
  )

df_promedio_continente_o <- df_i %>%
  group_by(Continent, Date) %>%
  summarise(
    O3_Promedio = mean(O3, na.rm = TRUE),
    .groups = "drop"
  )

df_promedio_continente_o %>%
  ggplot(aes(x = Date, y = O3_Promedio, color = Continent)) +
  
  geom_line(size = 0.8) +
  
  # CAMBIO CLAVE AQUÍ:
  # scales = "fixed" obliga a que todos los gráficos compartan el mismo eje Y.
  # (Es el comportamiento por defecto, así que también podrías borrar el argumento scales)
  facet_wrap(~ Continent, scales = "fixed", ncol = 2) +
  
  scale_color_viridis_d(option = "turbo") +
  theme_minimal() +
  labs(
    title = "Tendencia Promedio de O3 por Continente (Escala Comparativa)",
    subtitle = "Todos los paneles usan el mismo rango en el eje Y para comparar magnitudes",
    y = "Promedio O3",
    x = "Fecha"
  ) +
  theme(
    legend.position = "none", 
    strip.text = element_text(size = 11, face = "bold"),
    axis.text.x = element_text(angle = 45, hjust = 1),
    
    # Opcional: Agregar líneas de cuadrícula más claras para facilitar la lectura
    panel.grid.major.y = element_line(color = "gray90")
  )

# 1. PREPARACIÓN: Calculamos el PROMEDIO diario por PAÍS
df_promedio_pais <- df_i %>%
  group_by(Country, Date) %>%  # <--- Cambio clave: Agrupamos por País
  summarise(
    PM2.5_Promedio = mean(PM2.5, na.rm = TRUE),
    .groups = "drop"
  )

# 2. VISUALIZACIÓN: Paneles separados por País
df_promedio_pais %>%
  ggplot(aes(x = Date, y = PM2.5_Promedio, color = Country)) +
  
  geom_line(size = 0.7) + # Línea un poco más fina para que se vea limpia
  
  # Usamos facet_wrap por Country con escala FIJA
  # ncol = 4 organiza los gráficos en 4 columnas (ajusta este número según cuántos países tengas)
  facet_wrap(~ Country, scales = "fixed", ncol = 4) + 
  
  scale_color_viridis_d(option = "turbo") +
  theme_minimal() +
  labs(
    title = "Tendencia Promedio de PM2.5 por País (Escala Comparativa)",
    subtitle = "Todos los países bajo la misma escala vertical para comparar magnitud real",
    y = "Promedio PM2.5 (µg/m³)",
    x = "Fecha"
  ) +
  theme(
    legend.position = "none", 
    strip.text = element_text(size = 8, face = "bold"), # Texto un poco más pequeño para que quepa
    axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1), # Rotamos 90 grados si hay muchos paneles
    panel.grid.major.y = element_line(color = "gray90")
  )

# 1. PREPARACIÓN: Calculamos el PROMEDIO diario por PAÍS
df_promedio_pais_o <- df_i %>%
  group_by(Country, Date) %>%  # <--- Cambio clave: Agrupamos por País
  summarise(
    O3_Promedio = mean(O3, na.rm = TRUE),
    .groups = "drop"
  )

# 2. VISUALIZACIÓN: Paneles separados por País
df_promedio_pais_o %>%
  ggplot(aes(x = Date, y = O3_Promedio, color = Country)) +
  
  geom_line(size = 0.7) + # Línea un poco más fina para que se vea limpia
  
  # Usamos facet_wrap por Country con escala FIJA
  # ncol = 4 organiza los gráficos en 4 columnas (ajusta este número según cuántos países tengas)
  facet_wrap(~ Country, scales = "fixed", ncol = 4) + 
  
  scale_color_viridis_d(option = "turbo") +
  theme_minimal() +
  labs(
    title = "Tendencia Promedio de O3 por País (Escala Comparativa)",
    subtitle = "Todos los países bajo la misma escala vertical para comparar magnitud real",
    y = "Promedio O3",
    x = "Fecha"
  ) +
  theme(
    legend.position = "none", 
    strip.text = element_text(size = 8, face = "bold"), # Texto un poco más pequeño para que quepa
    axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1), # Rotamos 90 grados si hay muchos paneles
    panel.grid.major.y = element_line(color = "gray90")
  )

Ajustemos el Data set para tener información Mensual y por estaciones del año

meses_espanol <- c("ene", "feb", "mar", "abr", "may", "jun", 
                   "jul", "ago", "sep", "oct", "nov", "dic")

Q_labels <- c('Q-1','Q-2','Q-3','Q-4')

df_i2 = df_i %>% 
  mutate(
    Quarter = factor(quarter(Date),levels=1:4,labels=Q_labels) ,
    Month = factor(month(Date), levels = 1:12, labels = meses_espanol)
    
  )

df_i2 |> head()
## # A tibble: 6 × 16
##   City        Country Date       PM2.5  PM10   NO2   SO2    CO    O3 Temperature
##   <chr>       <chr>   <date>     <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>       <dbl>
## 1 Sydney      Austra… 2023-01-01  74.7  70.6  33.8  20.2  3.36  84.6        7.15
## 2 Rio de Jan… Brazil  2023-01-01  31.3  97.8  49.4  26.4  6.51 160.        15   
## 3 Toronto     Canada  2023-01-01 149.   98.0  73.0  43.5  9.38 178.        -5.05
## 4 Beijing     China   2023-01-01  70.9  60.7  53.4  38.2  5.61  33.8        7.39
## 5 Cairo       Egypt   2023-01-01  81.9  97.9  36.7  34.2  3.88 106.         2.16
## 6 Paris       France  2023-01-01  81.8  12.0  55.0  27.4  3.02  66.3        4.92
## # ℹ 6 more variables: Humidity <dbl>, Wind.Speed <dbl>, Continent <chr>,
## #   Hemisphere <chr>, Quarter <fct>, Month <fct>
df_i2 %>%
  mutate(Season = case_when
         (
           #Hemisferio Norte
           Hemisphere %in% c('North') & Month %in% c('dic','ene','feb') ~ "Winter",
           Hemisphere %in% c('North') & Month %in% c('mar','abr','may') ~ "Spring",
           Hemisphere %in% c('North') & Month %in% c('jun','jul','ago') ~ "Summer",
           Hemisphere %in% c('North') & Month %in% c('sep','oct','nov') ~ "Autumn",
           #Hemisferio Sur
           Hemisphere %in% c('South') & Month %in% c('dic','ene','feb') ~ "Summer",
           Hemisphere %in% c('South') & Month %in% c('mar','abr','may') ~ "Autumn",
           Hemisphere %in% c('South') & Month %in% c('jun','jul','ago') ~ "Winter",
           Hemisphere %in% c('South') & Month %in% c('sep','oct','nov') ~ "Spring"
         ))
## # A tibble: 7,240 × 17
##    City       Country Date       PM2.5  PM10   NO2   SO2    CO    O3 Temperature
##    <chr>      <chr>   <date>     <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>       <dbl>
##  1 Sydney     Austra… 2023-01-01  74.7  70.6  33.8  20.2  3.36  84.6        7.15
##  2 Rio de Ja… Brazil  2023-01-01  31.3  97.8  49.4  26.4  6.51 160.        15   
##  3 Toronto    Canada  2023-01-01 149.   98.0  73.0  43.5  9.38 178.        -5.05
##  4 Beijing    China   2023-01-01  70.9  60.7  53.4  38.2  5.61  33.8        7.39
##  5 Cairo      Egypt   2023-01-01  81.9  97.9  36.7  34.2  3.88 106.         2.16
##  6 Paris      France  2023-01-01  81.8  12.0  55.0  27.4  3.02  66.3        4.92
##  7 Berlin     Germany 2023-01-01 130.   87.5  86.3  41.4  5.17  28.5       -1.88
##  8 Mumbai     India   2023-01-01 111.  164.   76.7  31.0  2.60 151.        30.1 
##  9 Tokyo      Japan   2023-01-01  69.7 153.   18.4  37.5  5.28  31.4        2.72
## 10 Mexico Ci… Mexico  2023-01-01  45.9 181.   45.5  39.7  8.44  61.7       32.2 
## # ℹ 7,230 more rows
## # ℹ 7 more variables: Humidity <dbl>, Wind.Speed <dbl>, Continent <chr>,
## #   Hemisphere <chr>, Quarter <fct>, Month <fct>, Season <chr>
df_avg_continen_Month <- df_i2 %>%
  group_by(Continent, Month) %>%
  summarise(
    PM2.5_Promedio = mean(PM2.5, na.rm = TRUE),
    .groups = "drop"
  )

df_avg_continen_Month %>%
  ggplot(aes(x = Month, y = PM2.5_Promedio, color = Continent, group = Continent)) +
  
  geom_line(size = 0.5) +
  geom_point(size = 2) + 
  facet_wrap(~ Continent, scales = "fixed", ncol = 2) +
  scale_color_viridis_d(option = "turbo") +
  theme_minimal() +
  labs(
    title = "Tendencia Promedio de PM2.5 por Continente",
    subtitle = "Comparativa mensual",
    y = "Promedio PM2.5 (µg/m³)",
    x = "Mes"
  ) +
  theme(
    legend.position = "none", 
    strip.text = element_text(size = 11, face = "bold"),
    axis.text.x = element_text(angle = 0, hjust = 1),
    panel.grid.major.y = element_line(color = "gray90")
  )

df_avg_continen_Month <- df_i2 %>%
  group_by(Continent, Month) %>%
  summarise(
    O3_avg = mean(O3, na.rm = TRUE),
    .groups = "drop"
  )

df_avg_continen_Month %>%
  ggplot(aes(x = Month, y = O3_avg, color = Continent, group = Continent)) +
  
  geom_line(size = 0.5) +
  geom_point(size = 2) + 
  facet_wrap(~ Continent, scales = "fixed", ncol = 2) +
  scale_color_viridis_d(option = "turbo") +
  theme_minimal() +
  labs(
    title = "Tendencia Promedio de O3 por Continente",
    subtitle = "Comparativa mensual",
    y = "O3",
    x = "Mes"
  ) +
  theme(
    legend.position = "none", 
    strip.text = element_text(size = 11, face = "bold"),
    axis.text.x = element_text(angle = 0, hjust = 1),
    panel.grid.major.y = element_line(color = "gray90")
  )

Al parecer Sur Ámerica tiene los niveles más altos en espocas de calor

df_mensual_compare <- df_i2 %>% 
  group_by(Continent, Month) %>%
  summarise(
    PM2.5_Val = mean(PM2.5, na.rm = TRUE),
    O3_Val = mean(O3, na.rm = TRUE),
    .groups = "drop"
  )

max_pm <- max(df_mensual_compare$PM2.5_Val, na.rm = TRUE)
max_o3 <- max(df_mensual_compare$O3_Val, na.rm = TRUE)
coeff <- max_pm / max_o3 

df_mensual_compare %>%
  
  ggplot(aes(x = Month, group = Continent)) +
  
  geom_line(aes(y = PM2.5_Val, color = "PM2.5"), size = 1) +
  geom_point(aes(y = PM2.5_Val, color = "PM2.5"), size = 2) +
  
  geom_line(aes(y = O3_Val * coeff, color = "O3 (Ozono)"), size = 1, linetype = "dashed") +
  
  facet_wrap(~ Continent, scales = "fixed", ncol = 2) +
  
  scale_y_continuous(
    name = "Promedio PM2.5 (µg/m³)", 
    sec.axis = sec_axis(~ . / coeff, name = "Promedio Ozono (µg/m³)") 
  ) +
  
  scale_color_manual(values = c("PM2.5" = "#2c3e50", "O3 (Ozono)" = "#e67e22")) +
  theme_minimal() +
  labs(
    title = "Comparativa Estacional: PM2.5 vs Ozono",
    subtitle = "Línea Sólida = PM2.5 | Línea Punteada = Ozono",
    x = "Mes",
    color = "Contaminante"
  ) +
  theme(
    legend.position = "bottom",
    strip.text = element_text(size = 12, face = "bold"),
    axis.text.x = element_text(angle = 45, hjust = 1),
    
    axis.title.y.left = element_text(color = "#2c3e50", face = "bold"),
    axis.title.y.right = element_text(color = "#e67e22", face = "bold", vjust = 1.5)
  )

Deep Dive PM 2.5 por país

Por país

Hemisferio Norte

Africa - Egipto

df_avg_continen_Month <- df_i2 %>%
  filter(Country == 'Egypt')  %>%
  group_by(Country, Month) %>%
  summarise(
    PM2.5_Promedio = mean(PM2.5, na.rm = TRUE),
    .groups = "drop"
  )

df_avg_continen_Month %>%
  ggplot(aes(x = Month, y = PM2.5_Promedio, color = Country, group = Country)) +
  
  geom_line(size = 0.5) +
  geom_point(size = 2) + 
  facet_wrap(~ Country, scales = "fixed", ncol = 2) +
  scale_color_viridis_d(option = "turbo") +
  theme_minimal() +
  labs(
    title = "Tendencia Promedio de PM2.5 por País Asíatico",
    subtitle = "Comparativa mensual",
    y = "Promedio PM2.5 (µg/m³)",
    x = "Mes"
  ) +
  theme(
    legend.position = "none", 
    strip.text = element_text(size = 11, face = "bold"),
    axis.text.x = element_text(angle = 0, hjust = 1),
    panel.grid.major.y = element_line(color = "gray90")
  )

Egipto tiene un punto atípico en dic 2023 ¿por qué? #### Asia

df_avg_continen_Month <- df_i2 %>%
  filter(Continent == 'Asia')  %>%
  group_by(Country, Month) %>%
  summarise(
    PM2.5_Promedio = mean(PM2.5, na.rm = TRUE),
    .groups = "drop"
  )

df_avg_continen_Month %>%
  ggplot(aes(x = Month, y = PM2.5_Promedio, color = Country, group = Country)) +
  
  geom_line(size = 0.5) +
  geom_point(size = 2) + 
  facet_wrap(~ Country, scales = "fixed", ncol = 2) +
  scale_color_viridis_d(option = "turbo") +
  theme_minimal() +
  labs(
    title = "Tendencia Promedio de PM2.5 por País Asíatico",
    subtitle = "Comparativa mensual",
    y = "Promedio PM2.5 (µg/m³)",
    x = "Mes"
  ) +
  theme(
    legend.position = "none", 
    strip.text = element_text(size = 11, face = "bold"),
    axis.text.x = element_text(angle = 0, hjust = 1),
    panel.grid.major.y = element_line(color = "gray90")
  )

Europa

df_avg_continen_Month <- df_i2 %>%
  filter(Continent == 'Europe')  %>%
  group_by(Country, Month) %>%
  summarise(
    PM2.5_Promedio = mean(PM2.5, na.rm = TRUE),
    .groups = "drop"
  )

df_avg_continen_Month %>%
  ggplot(aes(x = Month, y = PM2.5_Promedio, color = Country, group = Country)) +
  
  geom_line(size = 0.5) +
  geom_point(size = 2) + 
  facet_wrap(~ Country, scales = "fixed", ncol = 2) +
  scale_color_viridis_d(option = "turbo") +
  theme_minimal() +
  labs(
    title = "Tendencia Promedio de PM2.5 por País Europeo",
    subtitle = "Comparativa mensual",
    y = "Promedio PM2.5 (µg/m³)",
    x = "Mes"
  ) +
  theme(
    legend.position = "none", 
    strip.text = element_text(size = 11, face = "bold"),
    axis.text.x = element_text(angle = 0, hjust = 1),
    panel.grid.major.y = element_line(color = "gray90")
  )

Norte Ámerica

df_avg_continen_Month <- df_i2 %>%
  filter(Continent == 'N-America')  %>%
  group_by(Country, Month) %>%
  summarise(
    PM2.5_Promedio = mean(PM2.5, na.rm = TRUE),
    .groups = "drop"
  )

df_avg_continen_Month %>%
  ggplot(aes(x = Month, y = PM2.5_Promedio, color = Country, group = Country)) +
  
  geom_line(size = 0.5) +
  geom_point(size = 2) + 
  facet_wrap(~ Country, scales = "fixed", ncol = 2) +
  scale_color_viridis_d(option = "turbo") +
  theme_minimal() +
  labs(
    title = "Tendencia Promedio de PM2.5 por País de Norte Ámerica",
    subtitle = "Comparativa mensual",
    y = "Promedio PM2.5 (µg/m³)",
    x = "Mes"
  ) +
  theme(
    legend.position = "none", 
    strip.text = element_text(size = 11, face = "bold"),
    axis.text.x = element_text(angle = 0, hjust = 1),
    panel.grid.major.y = element_line(color = "gray90")
  )

Verano (Jun-Ago en Norte): Deberías ver que el Ozono (Naranja) sube (por el sol) y a menudo el PM2.5 baja (por mejor dispersión del aire).

Invierno (Dic-Feb en Norte): El Ozono baja y el PM2.5 (Azul) suele subir (por inversiones térmicas y calefacción).

En México, CDMX sube en mayo los niveles PM 2.5…. en Canada que usualmente es frío y que en Mx y USA subieron los niveles, Canada bajan

Hemisferio Sur

Africa - South Africa

Para el Deep Dive de Hemisferio Sur, solo graficaremos a South Africa porque Oceanía y Sur Ámerica solo tienen un país CD
df_avg_continen_Month <- df_i2 %>%
  filter(Country == 'South Africa')  %>%
  group_by(Country, Month) %>%
  summarise(
    PM2.5_Promedio = mean(PM2.5, na.rm = TRUE),
    .groups = "drop"
  )

df_avg_continen_Month %>%
  ggplot(aes(x = Month, y = PM2.5_Promedio, color = Country, group = Country)) +
  
  geom_line(size = 0.5) +
  geom_point(size = 2) + 
  facet_wrap(~ Country, scales = "fixed", ncol = 2) +
  scale_color_viridis_d(option = "turbo") +
  theme_minimal() +
  labs(
    title = "Tendencia Promedio de PM2.5 por País Asíatico",
    subtitle = "Comparativa mensual",
    y = "Promedio PM2.5 (µg/m³)",
    x = "Mes"
  ) +
  theme(
    legend.position = "none", 
    strip.text = element_text(size = 11, face = "bold"),
    axis.text.x = element_text(angle = 0, hjust = 1),
    panel.grid.major.y = element_line(color = "gray90")
  )

Deep Dive O3 por país

Por país

Hemisferio Norte

Africa - Egipto

df_avg_continen_Month <- df_i2 %>%
  filter(Country == 'Egypt')  %>%
  group_by(Country, Month) %>%
  summarise(
    O3_Promedio = mean(O3, na.rm = TRUE),
    .groups = "drop"
  )

df_avg_continen_Month %>%
  ggplot(aes(x = Month, y = O3_Promedio, color = Country, group = Country)) +
  
  geom_line(size = 0.5) +
  geom_point(size = 2) + 
  facet_wrap(~ Country, scales = "fixed", ncol = 2) +
  scale_color_viridis_d(option = "turbo") +
  theme_minimal() +
  labs(
    title = "Tendencia Promedio de O3 para Egipto",
    subtitle = "Comparativa mensual",
    y = "O3",
    x = "Mes"
  ) +
  theme(
    legend.position = "none", 
    strip.text = element_text(size = 11, face = "bold"),
    axis.text.x = element_text(angle = 0, hjust = 1),
    panel.grid.major.y = element_line(color = "gray90")
  )

Egipto tiene un punto atípico en dic 2023 ¿por qué? #### Asia

df_avg_continen_Month <- df_i2 %>%
  filter(Continent == 'Asia')  %>%
  group_by(Country, Month) %>%
  summarise(
    O3_Promedio = mean(O3, na.rm = TRUE),
    .groups = "drop"
  )

df_avg_continen_Month %>%
  ggplot(aes(x = Month, y = O3_Promedio, color = Country, group = Country)) +
  
  geom_line(size = 0.5) +
  geom_point(size = 2) + 
  facet_wrap(~ Country, scales = "fixed", ncol = 2) +
  scale_color_viridis_d(option = "turbo") +
  theme_minimal() +
  labs(
    title = "Tendencia Promedio de O3 por País Asíatico",
    subtitle = "Comparativa mensual",
    y = "Promedio O3",
    x = "Mes"
  ) +
  theme(
    legend.position = "none", 
    strip.text = element_text(size = 11, face = "bold"),
    axis.text.x = element_text(angle = 0, hjust = 1),
    panel.grid.major.y = element_line(color = "gray90")
  )

Europa

df_avg_continen_Month <- df_i2 %>%
  filter(Continent == 'Europe')  %>%
  group_by(Country, Month) %>%
  summarise(
    O3_Promedio = mean(O3, na.rm = TRUE),
    .groups = "drop"
  )

df_avg_continen_Month %>%
  ggplot(aes(x = Month, y = O3_Promedio, color = Country, group = Country)) +
  
  geom_line(size = 0.5) +
  geom_point(size = 2) + 
  facet_wrap(~ Country, scales = "fixed", ncol = 2) +
  scale_color_viridis_d(option = "turbo") +
  theme_minimal() +
  labs(
    title = "Tendencia Promedio de O3 por País Europeo",
    subtitle = "Comparativa mensual",
    y = "Promedio O3)",
    x = "Mes"
  ) +
  theme(
    legend.position = "none", 
    strip.text = element_text(size = 11, face = "bold"),
    axis.text.x = element_text(angle = 0, hjust = 1),
    panel.grid.major.y = element_line(color = "gray90")
  )

Es extraño el comportamiento de Alemania por que desde agosto debería comenzar a bajar la temperatura y se ve una “montaña”. Más adelante lo cruzamos con temperatura

Norte Ámerica

df_avg_continen_Month <- df_i2 %>%
  filter(Continent == 'N-America')  %>%
  group_by(Country, Month) %>%
  summarise(
    O3_Promedio = mean(O3, na.rm = TRUE),
    .groups = "drop"
  )

df_avg_continen_Month %>%
  ggplot(aes(x = Month, y = O3_Promedio, color = Country, group = Country)) +
  
  geom_line(size = 0.5) +
  geom_point(size = 2) + 
  facet_wrap(~ Country, scales = "fixed", ncol = 2) +
  scale_color_viridis_d(option = "turbo") +
  theme_minimal() +
  labs(
    title = "Tendencia Promedio de O3 por País de Norte Ámerica",
    subtitle = "Comparativa mensual",
    y = "O3",
    x = "Mes"
  ) +
  theme(
    legend.position = "none", 
    strip.text = element_text(size = 11, face = "bold"),
    axis.text.x = element_text(angle = 0, hjust = 1),
    panel.grid.major.y = element_line(color = "gray90")
  )

Aparentemente hay un pico a la baja de O3 atípico en Canada, crucemos con Temperatura

Hemisferio Sur

Africa - South Africa

Para el Deep Dive de Hemisferio Sur, solo graficaremos a South Africa porque Oceanía y Sur Ámerica solo tienen un país CD
df_avg_continen_Month <- df_i2 %>%
  filter(Country == 'South Africa')  %>%
  group_by(Country, Month) %>%
  summarise(
    O3_Promedio = mean(O3, na.rm = TRUE),
    .groups = "drop"
  )

df_avg_continen_Month %>%
  ggplot(aes(x = Month, y = O3_Promedio, color = Country, group = Country)) +
  
  geom_line(size = 0.5) +
  geom_point(size = 2) + 
  facet_wrap(~ Country, scales = "fixed", ncol = 2) +
  scale_color_viridis_d(option = "turbo") +
  theme_minimal() +
  labs(
    title = "Tendencia Promedio de O3 por País Asíatico",
    subtitle = "Comparativa mensual",
    y = "O3",
    x = "Mes"
  ) +
  theme(
    legend.position = "none", 
    strip.text = element_text(size = 11, face = "bold"),
    axis.text.x = element_text(angle = 0, hjust = 1),
    panel.grid.major.y = element_line(color = "gray90")
  )

colnames(df_i2)
##  [1] "City"        "Country"     "Date"        "PM2.5"       "PM10"       
##  [6] "NO2"         "SO2"         "CO"          "O3"          "Temperature"
## [11] "Humidity"    "Wind.Speed"  "Continent"   "Hemisphere"  "Quarter"    
## [16] "Month"
tabla_promedios <- df_i2 %>%
  group_by(Country) %>%
  summarise(
    O3 = round(mean(O3, na.rm = TRUE), 2),
    PM2.5 = round(mean(PM2.5, na.rm = TRUE), 2),
    Temperatura = round(mean(Temperature, na.rm = TRUE), 2),
    Velocidad_Viento = round(mean(Wind.Speed, na.rm = TRUE), 2), 
    Humedad = round(mean(Humidity, na.rm = TRUE), 2)
  ) %>%
  
  # Opcional: Ordenar por PM2.5 de mayor a menor para ver los más contaminados arriba
  arrange(desc(PM2.5))

# Ver la tabla en consola
print(tabla_promedios)
## # A tibble: 19 × 6
##    Country         O3 PM2.5 Temperatura Velocidad_Viento Humedad
##    <chr>        <dbl> <dbl>       <dbl>            <dbl>   <dbl>
##  1 UAE          108.   81          15              10.8     56.9
##  2 India        104.   79.8        14.1            10.5     54.1
##  3 China        106.   79.2        15              10.5     54.4
##  4 Canada       110.   78.8        15.2            10.6     55.9
##  5 Australia    103.   78          13.9            10.1     56.8
##  6 Mexico       107.   77.8        15.4            10.4     56.2
##  7 Germany      101.   77.8        15.3            10.2     53.0
##  8 Thailand      97.3  77.6        14.6            10.6     57.8
##  9 UK           105.   77.0        16.1            10.3     56.6
## 10 Russia       106.   77.0        16              10.1     55.5
## 11 USA          105.   76.9        14.8             9.82    53.2
## 12 Brazil       108.   76.9        16.4            10.5     55.0
## 13 Turkey       105.   76.8        14.8            10.0     54.8
## 14 Japan        110.   76.8        13.8            10.7     54.0
## 15 South Africa 108.   76.7        14.7             9.62    55.8
## 16 Egypt        107.   76.7        14.8             9.71    53.0
## 17 Spain        103.   75.0        14.7             9.91    52.3
## 18 South Korea  109.   74.9        15.7            10.2     56.6
## 19 France       108.   73.6        14.5            10       56.9
tabla_larga <- tabla_promedios %>%
  pivot_longer(
    cols = -Country,       # Tomamos todas las columnas menos el País
    names_to = "Variable", # Nombre de la nueva columna de categorías
    values_to = "Valor"    # Nombre de la nueva columna de valores
  )

# 2. Creamos el Gráfico Facetado
ggplot(tabla_larga, aes(x = reorder(Country, Valor), y = Valor, fill = Variable)) +
  
  geom_col(show.legend = FALSE) + # Barras sin leyenda (el título lo dice)
  
  coord_flip() + # Volteamos el gráfico para leer bien los nombres de países
  
  # CRUCIAL: scales = "free_x" permite que cada métrica tenga su propia escala
  facet_wrap(~ Variable, scales = "free_x", ncol = 3) +
  
  scale_fill_viridis_d() + # Colores bonitos
  theme_minimal() +
  labs(
    title = "Comparativa de Promedios por País",
    subtitle = "Cada panel muestra el ranking de países para esa variable específica",
    x = "",
    y = "Valor Promedio"
  ) +
  theme(
    strip.text = element_text(face = "bold", size = 10),
    axis.text.y = element_text(size = 7) # Texto un poco más pequeño si hay muchos países
  )

# 1. Seleccionamos solo las columnas numéricas de tu dataset completo
# (Asegúrate de excluir columnas categóricas como City, Country, Month, etc.)
datos_numericos <- df_i2 %>% 
  select(PM2.5, PM10, NO2, SO2, CO, O3, Temperature, Humidity,Wind.Speed) 

# 2. Calculamos la matriz matemática de correlación
matriz_cor <- cor(datos_numericos, use = "complete.obs")

# 3. Graficamos
ggcorrplot(matriz_cor, 
           method = "circle",       # O "square"
           type = "lower",          # Muestra solo la mitad inferior (para no repetir)
           lab = TRUE,              # Muestra el número de correlación dentro
           lab_size = 3,            # Tamaño del número
           colors = c("#E46726", "white", "#6D9EC1"), # Rojo (Negativo) - Blanco - Azul (Positivo)
           title = "Matriz de Correlación: Clima y Contaminantes",
           ggtheme = ggplot2::theme_minimal)

# 1. Obtenemos la lista única de continentes
continentes <- unique(df_i2$Continent)

# 2. Iniciamos el bucle para generar un gráfico por cada uno
for(cont in continentes) {
  
  # A. Filtramos los datos SOLO para ese continente
  datos_continente <- df_i %>%
    filter(Continent == cont) %>%
    # Seleccionamos solo las numéricas (igual que antes)
    select(PM2.5, PM10, NO2, SO2, CO, O3, Temperature, Humidity, Wind.Speed)
  
  # B. Calculamos la correlación
  # (Usamos tryCatch por si algún continente tiene pocos datos y falla, que el código siga)
  try({
    matriz_cor <- cor(datos_continente, use = "complete.obs")
    
    # C. Creamos el Gráfico
    p <- ggcorrplot(matriz_cor, 
               method = "circle",
               type = "lower",
               lab = TRUE, 
               lab_size = 3, 
               colors = c("#E46726", "white", "#6D9EC1"),
               title = paste("Matriz de Correlación -", cont), # Título dinámico
               ggtheme = ggplot2::theme_minimal)
    
    # D. Imprimimos el gráfico en pantalla
    print(p)
    
  }, silent = TRUE)
}

# 1. Obtenemos la lista única de continentes
paises <- unique(df_i2$Country)

# 2. Iniciamos el bucle para generar un gráfico por cada uno
for(pais in paises) {
  
  # A. Filtramos los datos SOLO para ese continente
  datos_pais <- df_i %>%
    filter(Country == pais) %>%
    # Seleccionamos solo las numéricas (igual que antes)
    select(PM2.5, PM10, NO2, SO2, CO, O3, Temperature, Humidity, Wind.Speed)
  
  # B. Calculamos la correlación
  # (Usamos tryCatch por si algún continente tiene pocos datos y falla, que el código siga)
  try({
    matriz_cor <- cor(datos_pais, use = "complete.obs")
    
    # C. Creamos el Gráfico
    p <- ggcorrplot(matriz_cor, 
               method = "circle",
               type = "lower",
               lab = TRUE, 
               lab_size = 3, 
               colors = c("#E46726", "white", "#6D9EC1"),
               title = paste("Matriz de Correlación -", pais), # Título dinámico
               ggtheme = ggplot2::theme_minimal)
    
    # D. Imprimimos el gráfico en pantalla
    print(p)
    
  }, silent = TRUE)
}